render hooks パターン
【LINE証券 FrontEnd】コンポーネントをカスタムフックで提供してみた - LINE ENGINEERING
react hooksで、コンポーネント(のReact.ReactNode)を返すテクニックのこと
状態とコンポーネントを両方渡す時に便利
↑のLINE証券の記事でuhyo氏がこのパターンを命名してくれたおかげで、ググりやすくなった
これ以前でも、hooksからelement返すのはやったことある人は多分いると思うから起源は分からん
起源は追わなくてもいいかなと思う
命名してくれたことが偉いと思う
code:ts
const App: React.FC = () => {
const isAllChecked, node = useChecks(labels)
return (
<div>
{node}
<p>
<button disabled={!isAllChecked}>次へ</button>
</p>
</div>
)
}
モーダルの実装なんかも
code:js
const App: React.FC = () => {
const {isOpen, open , node} = useModal()
return (
<div>
{node}
<button onClick={open}>開く</button>
</div>
)
}
twitterで検索すると、このパターンに対して不安を感じる声がある
hooksは単なる関数であり、ReactElementは単なるJSのオブジェクトに過ぎないので何も問題ない
不安を覚えるなら、そもそもJavaScriptでUIを構築することに不安を覚えても良いのでは?
hooksライブラリからコンポーネントを返したいことはあんまりないので、ライブラリにて採用されてる実例は少ない
このパターンを利用すべきケースは、ライブラリじゃなくてアプリケーション側のほうが発生しやすいと思われる
Element(ReactNode)を返すべきかFC ( ()=>Element)を返すべきか
@uhyo_: 「hooksからコンポーネントを返す」と言われたときにReact.FCを返すやつとJSX.Elementを返すやつが混同されている懸念がある。ぼくが推してるのはJSX.Elementを返すほうです(?)
@uhyo_: React.FCを返すほうはあまり良くないと思う。というのもステートを内包させると必然的にステートが変わると別の関数オブジェクトになり、再レンダリング時にパフォーマンスのペナルティがあるから🫐
たしかにmiyamonz.icon
でもLINE証券の記事では後者なんだな
Element直返しで良いと思ってるが、何か後から渡す引数があるなら、(arg)=>Elementでもいいだろう
render hooks パターン#648a7595385a920000bddfbe
この記事にもあるように、結局FC(関数)を渡せば、それはobjectの同一性においてレンダリングのたびに異なるelementが作られうるので、基本はelementを返すのが正しい
react-hooks-use-modalを使ってモーダルコンポーネントを作成する | microCMSブログ
ここで紹介されてるreact-hooks-use-modalもこのパターンと言える
こっちはFCを返してる
@uhyo_: そうだな。childrenは特殊な構文を与えられたrender propsであると考えたほうが幸せになりそう。レイアウトの責務を持つコンポーネントだとslotが1つだと普通に足りないときがあるし(?)
そのとおりすぎて、childrenがReactNodeなのだから、別のpropにわたす変数もReactNode(Element)で保持して良いに決まってるmiyamonz.icon
そもそも、react elementを普段遣いのオブジェクトとして触りつつ、それを関数で返すようになると勝手にrender hooksになる
ただし厳密には、内部にuseState, useEffectなどが無いようなものは、hooksでは無く単なる関数で
コンポーネントレンダリング時にif文で分岐させてはいけない系の制約もなくなる
記事
render hooks パターンの素振り
fileのinput要素と、渡されたdataURLを返す
useStateのsetをコンポーネントとして受け取ると考えるとたしかにこれは良いか
値をユーザから受け取って、必要な情報を取り出すというロジックをrender hooks内に閉じ込められる、と考えられる
さらに、プレビュー画面もコンポーネントにしてしまうのも書いている
render hooks パターンの注意点と対策
良く考えたらそりゃそうだなmiyamonz.icon
しかし、これが当たり前、と言えるのはReactをある程度習熟してないとむずそうだな
あまり海外の文献は見当たらない
https://www.perplexity.ai/search/what-is-render-hooks-y7xYG_aHQBW_4v2j.L8alw